﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using EmoneyWeiXinCommon;
using EmoneyWeiXinEntity;
using EmoneyWeiXinThreadDAL;
using EmoneyWeiXinDAL;

namespace EmoneyWeiXinThreadBLL
{
    public class ThreadWeiXinBLL
    {
        public static Thread thtbData5 = null;
        public static Thread thtbData1 = null;
        public static weixinUserDal dalWeixinuser = new weixinUserDal();
        public static List<weixinUserEntity> listweixinUser = new List<weixinUserEntity>();
        public static MemcachedTools1 mmtols = new MemcachedTools1();
        public static List<NewsReportEntity> ListnewsReport = new List<NewsReportEntity>();
        public static newsReportDAL newsreDal = new newsReportDAL();
        public static List<MenuEntity> listMc = new List<MenuEntity>();

        public static void ThreadStart()
        {
            thtbData5 = new Thread(getLoadData);
            thtbData5.Start();

            thtbData1 = new Thread(GetTongBu);
            thtbData1.Start();
        }

        /// <summary>
        /// 线程同步栏目数据
        /// </summary>
        public static void GetTongBu()
        {
            DateTime dtStart1 = System.DateTime.Now;
            while (true)
            {
                dtStart1 = System.DateTime.Now;

                getReplyManagerCache();
                GetKeyWordManageCache();
                getNewsReportCache();
                GetKeyWordManager_NewsReportCache();
                GetReplyManager_NewsReportCache();
                SendModelMessage();
                GetMenuReportMergeData();
                GetHotsZTCode();
                GetTuSong(System.DateTime.Now);
                int sleepTime = 120 * 1000 - Convert.ToInt32((System.DateTime.Now - dtStart1).TotalSeconds * 1000);
                if (sleepTime < 0)
                {
                    sleepTime = 1000;
                }
                Thread.Sleep(sleepTime);
            }
        }

        /// <summary>
        /// 盘算是否推送数据
        /// </summary>
        /// 
        public static void GetTuSong(DateTime dtstart)
        {
            getMemuAll();

            if (listMc != null && listMc.Count > 0)
            {
                string[] strArr = null;
                string keys = "";
                foreach (MenuEntity item in listMc)
                {
                    if (item.DayType == 1 || (item.DayType == 2 && !string.IsNullOrEmpty(item.thday) && item.thday.Contains(StringTools.getWeekday(System.DateTime.Now))))
                    {
                        if (!string.IsNullOrEmpty(item.jgtimeStr))
                        {
                            strArr = item.jgtimeStr.Split(',');
                            for (int i = 0; i < strArr.Length; i++)
                            {
                                if (Convert.ToInt32(strArr[i].Replace(":", "")) <= Convert.ToInt32(dtstart.ToString("HHmm")) && Convert.ToInt32(strArr[i].Replace(":", "")) >= Convert.ToInt32(dtstart.AddMinutes(-10).ToString("HHmm")))
                                {
                                    keys = StringTools.ChangeRealKey("tuisong", item.weixinuserid.ToString() + item.everyKey + dtstart.ToString("yyyy-MM-dd") + strArr[i]);
                                    object obj = mmtols.Get(keys);
                                    if (obj == null)
                                    {
                                        getTuiSongUser(item.weixinuserid.ToString(), item.everyKey);
                                        mmtols.Add(keys, "已推送", 24, 0, 0);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 推送数据
        /// </summary>
        /// <param name="weixinid"></param>
        /// <param name="memuType"></param>
        public static void getTuiSongUser(string weixinid, string memuType, string dingou = "")
        {
            string keys = StringTools.ChangeRealKey("newsreport", weixinid + memuType);
            var queryKeys = mmtols.Get(keys);
            PropellingLogEntity pplogEntity = new PropellingLogEntity();
            if (queryKeys != null)
            {
                NewsReportEntity newsr = JsonTools.ToObject<NewsReportEntity>(queryKeys.ToString());
                if (Convert.ToDouble(newsr.pubDate.ToString("yyyyMMdd")) >= Convert.ToDouble(System.DateTime.Now.ToString("yyyyMMdd")))
                {
                    if (newsr.PubStatus == 1)
                    {
                        string strJson = getNewsPortJson(newsr);
                        if (listweixinUser == null || listweixinUser.Count < 0)
                        {
                            getWeixinUser();
                        }
                        if (listweixinUser != null && listweixinUser.Count > 0)
                        {
                            var query = listweixinUser.Where(x => x.id == Convert.ToInt32(weixinid)).ToList();
                            if (query != null && query.Count > 0)
                            {
                                for (int i = 0; i < query.Count; i++)
                                {
                                    if (!string.IsNullOrEmpty(query[i].AppId) && !string.IsNullOrEmpty(query[i].AppSecret))
                                    {
                                        string strtoken = TokenHelper.GetToken(query[i].AppId, query[i].AppSecret);
                                        if (string.IsNullOrEmpty(dingou))
                                        {
                                            string str = "";
                                            string nextopenid = "";
                                            getUserEntity user = new getUserEntity();
                                            while (true)
                                            {
                                                str = TokenHelper.GetUser(query[i].AppId, strtoken, nextopenid);
                                                user = JsonTools.ToObject<getUserEntity>(str);
                                                if (user != null && user.count > 0)
                                                {
                                                    for (int j = 0; j < user.data.openid.Length; j++)
                                                    {
                                                        string tojson1 = strJson.Replace("{0}", user.data.openid[j]);
                                                        tojson1 = tojson1.Replace("{1}", query[i].id.ToString());
                                                        ThreadPolPicTuiSong thread = new ThreadPolPicTuiSong(tojson1, strtoken, user.data.openid[j], newsr.ID.ToString(), query[i].id, 1);
                                                        ThreadPool.QueueUserWorkItem(new WaitCallback(thread.ThreadProc), thread);
                                                    }
                                                    if (user.count == 10000)
                                                    {
                                                        nextopenid = user.next_openid;
                                                    }
                                                    else
                                                    {
                                                        break;
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            var querystockuser = dalWeixinuser.getStockdoctorUser(weixinid, dingou, newsr.MemuType);
                                            foreach (StockDoctorloguserEntity item in querystockuser)
                                            {
                                                string tojson1 = strJson.Replace("{0}", item.FromUserName);
                                                tojson1 = tojson1.Replace("{1}", query[i].id.ToString());
                                                ThreadPolPicTuiSong thread = new ThreadPolPicTuiSong(tojson1, strtoken, item.FromUserName, newsr.ID.ToString(), query[i].id, 2);
                                                ThreadPool.QueueUserWorkItem(new WaitCallback(thread.ThreadProc), thread);
                                            }
                                        }
                                    }
                                }
                                newsreDal.newsReportUpdatefbzt(newsr.ID.ToString());
                            }
                        }
                    }
                }
                else
                {
                    StringTools.GetSendMail("当日无最新数据：" + queryKeys);
                }
            }
        }

        public static void getReplyManagerCache()
        {
            var listreply = newsreDal.getReplyManagerEntityAll();
            if (listreply != null && listreply.Count > 0)
            {
                string keys = "";
                foreach (ReplyManagerEntity item in listreply)
                {
                    keys = StringTools.ChangeRealKey("reply", item.weixinid.ToString() + item.hisid.ToString());
                    if (item.isvalid == 1)
                    {
                        mmtols.Add(keys, JsonTools.ToJson(item), 24 * 365, 0, 0);
                    }
                    else
                    {
                        mmtols.Remove(keys);
                    }
                }
                listreply.Clear();
            }
        }
        //关键字缓存
        public static void GetKeyWordManageCache()
        {
            var lstkeyWord = newsreDal.GetKeyWordManagerEntityAll();
            if (lstkeyWord != null && lstkeyWord.Count > 0)
            {
                foreach (KeyWordManagerEntity item in lstkeyWord)
                {
                    string key = StringTools.ChangeRealKey("keyWordRply", item.weixinid + item.keyword);
                    if (item.isdel == 1 || item.isvalid != 1)
                    {
                        mmtols.Remove(key);
                    }
                    else
                    {
                        mmtols.Add(key, JsonTools.ToJson(item), 24 * 365, 0, 0);
                    }
                }
                lstkeyWord.Clear();
            }
        }

        public static void GetKeyWordManager_NewsReportCache()
        {
            var lstkeyWordNewsReport = newsreDal.GetKeyWordManager_NewsReport();
            var grouped = lstkeyWordNewsReport.GroupBy(n => (n.weixinid + n.keyword));
            Dictionary<string, List<NewsReportEntity>> dic = new Dictionary<string, List<NewsReportEntity>>();
            foreach (var item in grouped)
            {
                List<NewsReportEntity> rs = new List<NewsReportEntity>();
                string currentKey = "";
                foreach (var item2 in item)
                {
                    currentKey = item2.weixinid + item2.keyword;
                    rs.Add(new NewsReportEntity()
                    {
                        ID = item2.newsreport_id,
                        Summary = item2.Summary,
                        ImageUrl = item2.ImageUrl,
                        OutsideUrl = item2.OutsideUrl,
                        title = item2.title
                    });
                }
                dic.Add(currentKey, rs);
            }

            foreach (string item in dic.Keys)
            {
                string mmKey = StringTools.ChangeRealKey("keyWordReport", item);
                mmtols.Add(mmKey, dic[item], 24 * 365, 0, 0);
            }
        }

        public static void GetReplyManager_NewsReportCache()
        {
            string key = "";
            var lstreplyNewsReport = newsreDal.GetReplyManager_NewsReport();
            if (lstreplyNewsReport != null && lstreplyNewsReport.Count > 0)
            {
                var query1 = lstreplyNewsReport.GroupBy(x => x.replyid).Select(x => x.First()).ToList();
                if (query1 != null && query1.Count > 0)
                {
                    for (int i = 0; i < query1.Count; i++)
                    {
                        var query2 = lstreplyNewsReport.Where(x => x.replyid == query1[i].replyid).ToList();
                        List<NewsReportEntity> newsList = new List<NewsReportEntity>();
                        foreach (ReplyManager_NewsReportEntity1 item in query2)
                        {
                            key = StringTools.ChangeRealKey("newsreport", item.weixinid.ToString() + item.newsreport_id.ToString());
                            var objValue = mmtols.Get(key);
                            if (objValue == null)
                            {
                                NewsReportEntity ne = newsreDal.GetNewsReportById(item.newsreport_id);
                                mmtols.Add(key, ne, 365 * 24, 0, 0);
                            }
                            newsList.Add(new NewsReportEntity()
                            {
                                OutsideUrl = item.OutsideUrl,
                                ImageUrl = item.OutsideUrl,
                                Summary = item.Summary,
                                ID = item.newsreport_id,
                                title = item.title
                            });

                        }

                        key = StringTools.ChangeRealKey("replyReports", query1[i].replyid.ToString());
                        mmtols.Add(key, newsList, 24 * 365, 0, 0);
                    }
                    query1.Clear();
                }
                lstreplyNewsReport.Clear();
            }
        }


        public static void GetMenuReportMergeData()
        {
            List<MenuReportMergeEntity> lst = newsreDal.GetMenuReportMergeData();
            var grouped = lst.GroupBy(n => n.weixinId + n.menuType);
            Dictionary<string, List<NewsReportEntity>> dic = new Dictionary<string, List<NewsReportEntity>>();
            foreach (var item in grouped)
            {
                List<NewsReportEntity> rs = new List<NewsReportEntity>();
                string currentKey = "";
                foreach (var item2 in item)
                {
                    currentKey = item2.weixinId + item2.menuType;
                    rs.Add(new NewsReportEntity()
                    {
                        ID = item2.newsReportId,
                        Summary = item2.Summary,
                        ImageUrl = item2.ImageUrl,
                        OutsideUrl = item2.OutsideUrl,
                        title = item2.title
                    });
                }
                dic.Add(currentKey, rs);
            }
            foreach (string item in dic.Keys)
            {
                string mmKey = StringTools.ChangeRealKey("MenuReportMerge", item);
                mmtols.Add(mmKey, dic[item], 24 * 365, 0, 0);
            }
        }


        /// <summary>
        /// 加载菜单数据
        /// </summary>
        public static void getMemuAll()
        {
            try
            {
                listMc = dalWeixinuser.getMemuAll();
                var query = dalWeixinuser.getMemuAll1();
                if (query != null && query.Count > 0)
                {
                    string keys = "";
                    foreach (MenuEntity item in query)
                    {
                        keys = StringTools.ChangeRealKey("memu", item.weixinuserid.ToString() + item.everyKey);
                        mmtols.Add(keys, item, 24 * 30, 0, 0);
                        if (!string.IsNullOrEmpty(item.Keyword))
                        {
                            var querykeyword = item.Keyword.Split(',');
                            if (querykeyword != null && querykeyword.Length > 0)
                            {
                                keys = StringTools.ChangeRealKey("newsreport", item.weixinuserid + item.everyKey);
                                var keyvalues = mmtols.Get(keys);
                                for (int i = 0; i < querykeyword.Length; i++)
                                {
                                    keys = StringTools.ChangeRealKey("newsreport", item.weixinuserid + querykeyword[i]);
                                    mmtols.Add(keys, keyvalues, 24 * 365, 0, 0);
                                }
                            }
                        }
                    }
                }
                query.Clear();

            }
            catch (Exception ex)
            {
                StringTools.GetSendMail("EmoneyWeiXinThreadBLL.ThreadWeiXinBLL.getMemuAll().error:" + ex);
            }
        }

        /// <summary>
        /// 加载必要的数据
        /// </summary>
        public static void getLoadData()
        {
            while (true)
            {
                getWeixinUser();

                getMemuAll();

                Thread.Sleep(60 * 1000);
            }
        }

        /// <summary>
        /// 加载微信用户数据
        /// </summary>
        public static void getWeixinUser()
        {
            listweixinUser = dalWeixinuser.getWeixinUserAll();
            if (listweixinUser != null && listweixinUser.Count > 0)
            {
                string keys = "";
                for (int i = 0; i < listweixinUser.Count; i++)
                {
                    keys = StringTools.ChangeRealKey("weixinUser", listweixinUser[i].id.ToString());
                    mmtols.Add(keys, JsonTools.ToJson(listweixinUser[i]), 24 * 365, 0, 0);
                }
            }
        }

        public static object objnewsreport = new object();
        public static void getNewsReportCache()
        {
            try
            {
                lock (objnewsreport)
                {
                    string refreshStr = StringTools.GetListSelect("EmoneyWeiXinNewsReport");
                    if (string.IsNullOrEmpty(refreshStr))
                    {
                        refreshStr = "2015-03-01";
                    }
                    string keys = "";
                    string strContainkey = ",";
                    MyTrace.get().add("refreshStr:" + refreshStr);
                    ListnewsReport = newsreDal.getNewsReportUpDataAll(refreshStr);
                    if (ListnewsReport != null && ListnewsReport.Count > 0)
                    {
                        StringTools.GetListUpdate("EmoneyWeiXinNewsReport", ListnewsReport[0].updatetime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                        foreach (NewsReportEntity item in ListnewsReport)
                        {
                            if (!string.IsNullOrEmpty(item.keyword))
                            {
                                string[] strArrAy = item.keyword.Split(',');
                                for (int j = 0; j < strArrAy.Length; j++)
                                {
                                    if (!strContainkey.Contains("," + item.weixinid + strArrAy[j] + ","))
                                    {
                                        strContainkey += item.weixinid + strArrAy[j] + ",";
                                        keys = StringTools.ChangeRealKey("newsreport", item.weixinid + strArrAy[j]);
                                        mmtols.Add(keys, JsonTools.ToJson(item), 24 * 365, 0, 0);
                                    }
                                }
                            }
                            keys = StringTools.ChangeRealKey("newsreport", item.weixinid + item.ID.ToString());
                            mmtols.Add(keys, JsonTools.ToJson(item), 24 * 365, 0, 0);
                            if (!string.IsNullOrEmpty(item.newguid))
                            {
                                keys = StringTools.ChangeRealKey("newsreport", item.weixinid + item.newguid);
                                mmtols.Add(keys, JsonTools.ToJson(item), 24 * 365, 0, 0);
                            }
                        }
                        ListnewsReport.Clear();
                        ListnewsReport = new List<NewsReportEntity>();
                    }


                    ListnewsReport = newsreDal.getNewsReportUpDataAllLM();
                    strContainkey = ",";
                    if (ListnewsReport != null && ListnewsReport.Count > 0)
                    {
                        foreach (NewsReportEntity item in ListnewsReport)
                        {
                            if (!string.IsNullOrEmpty(item.MemuType) && !strContainkey.Contains("," + item.weixinid + item.MemuType + ","))
                            {
                                strContainkey += item.weixinid + item.MemuType + ",";
                                keys = StringTools.ChangeRealKey("newsreport", item.weixinid + item.MemuType);
                                mmtols.Add(keys, JsonTools.ToJson(item), 24 * 365, 0, 0);

                                keys = StringTools.ChangeRealKey("newsreport", item.weixinid.ToString() + item.ID.ToString());
                                mmtols.Add(keys, JsonTools.ToJson(item), 24 * 365, 0, 0);
                            }
                        }
                        ListnewsReport.Clear();
                        ListnewsReport = new List<NewsReportEntity>();
                    }

                }

            }
            catch (Exception ex)
            {
                StringTools.GetSendMail("getNewsReportCache:" + ex.Message);
            }
        }


        public static void GetHotsZTCode()
        {
            try
            {
                List<string> list = newsreDal.GetHotsZTCode();
                string key = StringTools.ChangeRealKey("codeHots", "123");
                mmtols.Add(key, list, 1, 0, 0);
            }
            catch (Exception)
            {

            }

        }

        public static void SendModelMessage()
        {
            ModelMessagesDAL dal = new ModelMessagesDAL();
            List<ModelMessagesEntity> lst = dal.GetTop100NotSendList();
            if (lst.Count > 0)
            {

                string accessToken = string.Empty;
                string mmkey = StringTools.ChangeRealKey("weixinUser", lst[0].weixinId.ToString());
                weixinUserEntity weixinuser = JsonTools.ToObject<weixinUserEntity>(mmtols.Get(mmkey).ToString());
                accessToken = TokenHelper.GetToken(weixinuser.AppId, weixinuser.AppSecret);
                foreach (var item in lst)
                {
                    try
                    {
                        dal.UpdateStatus(item.Id, 1); //将消息的状态设为正在发送的状态
                        bool isRefreshToken; //是否需要刷新token
                        bool sendResult = EmoneyWeiXinCommon.SendModelMessage.Send(accessToken, item, out isRefreshToken);
                        if (isRefreshToken)
                        {
                            TokenHelper.ClearToken(weixinuser.AppId);
                            accessToken = TokenHelper.GetToken(weixinuser.AppId, weixinuser.AppSecret);
                            sendResult = EmoneyWeiXinCommon.SendModelMessage.Send(accessToken, item, out isRefreshToken);
                        }
                        dal.UpdateStatus(item.Id, sendResult ? 2 : 0);
                    }
                    catch (Exception ex)
                    {
                        MyTrace.get().add("EmoneyWeiXinThreadBLL.SendModelMessage:" + ex.Message);
                    }

                }
            }

        }

        /// <summary>
        /// 推送json数据拼接
        /// </summary>
        /// <param name="newsr"></param>
        /// <returns></returns>
        public static string getNewsPortJson(NewsReportEntity newsr)
        {
            string strContext = "";
            strContext += "{";
            strContext += "\"touser\":\"{0}\",";
            strContext += "\"msgtype\":\"news\",";
            strContext += "\"news\":{";
            strContext += "\"articles\": [";

            strContext += "{";
            strContext += "\"title\":\"" + newsr.title + "\",";
            strContext += "\"description\":\"" + newsr.Summary + "\",";
            strContext += "\"url\":\"" + Config.selNewsReportUrl + "?fn={0}&weixinid={1}&id=" + newsr.ID + "\",";
            strContext += "\"picurl\":\"" + newsr.ImageUrl + "\"";
            strContext += "}";

            strContext += "]";
            strContext += "}";
            strContext += "}";

            return strContext;
        }

    }
}
